package com.gwtintegration.smartrf.builder;

import java.util.List;
import java.util.Set;

import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.user.rebind.SourceWriter;

public class ProxyCollectionFieldConverterBuilder extends FieldConverterBuilder {

	protected ProxyCollectionFieldConverterBuilder(JMethod getterMethod, ProxyConverterBuilder proxyConverterBuilder) {
		super(getterMethod, proxyConverterBuilder);
	}

	@Override
	public boolean buildToProxy(SourceWriter sourceWriter) {

		if (!hasSetterMethod()) {
			return false;
		}

		JMethod setterMethod = getSetterMethod();
		JClassType parameterType = JMethodUtils.getSingleParameterType(setterMethod);
		JParameterizedType parameterized = parameterType.isParameterized();
		JClassType parameter = JTypeUtils.getSingleParameterType(parameterized);

		if (Set.class.getName().equals(parameterized.getBaseType().getQualifiedSourceName())) {
			sourceWriter.println("%s %s  = new java.util.HashSet<%s>();", parameterType.getParameterizedQualifiedSourceName(), getVariableName(),
					parameter.getName());
		} else if (List.class.getName().equals(parameterized.getBaseType().getQualifiedSourceName())) {
			sourceWriter.println("%s %s  = new java.util.ArrayList<%s>();", parameterType.getParameterizedQualifiedSourceName(), getVariableName(),
					parameter.getName());
		}

		sourceWriter.println("RecordList %sRecords = record.getAttributeAsRecordList(\"%s\");", getVariableName(), getAttributeName());
		sourceWriter.println("if(%sRecords != null && !%sRecords.isEmpty()) {", getVariableName(), getVariableName());
		sourceWriter.indent();

		sourceWriter.println("for(int i = 0; i < %sRecords.getLength(); i++) {", getVariableName());
		sourceWriter.indent();
		sourceWriter.println("%s childProxy = %s.this.toProxy(%sRecords.get(i), requestContext, \"%s\", converterCache);", parameter.getName(),
				getProxyConverterBuilder().getConverterBuilder().getClassName(), getVariableName(), parameter.getQualifiedSourceName());
		sourceWriter.println("%s.add(childProxy);", getVariableName());
		sourceWriter.outdent();
		sourceWriter.println("}");

		sourceWriter.outdent();
		sourceWriter.println("}");

		sourceWriter.println("proxy.%s(%s);", setterMethod.getName(), getVariableName());

		return true;
	}

	@Override
	public boolean buildToRecord(SourceWriter sourceWriter) {
		JMethod getterMethod = getGetterMethod();
		JClassType returnType = getterMethod.getReturnType().isClassOrInterface();
		JParameterizedType parameterized = returnType.isParameterized();
		JClassType parameter = JTypeUtils.getSingleParameterType(parameterized);

		sourceWriter.println(returnType.getParameterizedQualifiedSourceName() + " " + getVariableName() + " = proxy." + getterMethod.getName()
				+ "();");
		sourceWriter.println("if(%s != null && !%s.isEmpty()) {", getVariableName(), getVariableName());
		sourceWriter.indent();

		sourceWriter.println("RecordList %sRecords = new RecordList();", getVariableName());
		sourceWriter.println("for(%s value : %s) {", parameter.getName(), getVariableName());
		sourceWriter.indent();
		sourceWriter.println("%sRecords.add(%s.this.toRecord(value, \"%s\", converterCache));", getVariableName(), getProxyConverterBuilder()
				.getConverterBuilder().getClassName(), parameter.getQualifiedSourceName());
		sourceWriter.outdent();
		sourceWriter.println("}");

		sourceWriter.println("record.setAttribute(\"%s\", %sRecords);", getAttributeName(), getVariableName());
		sourceWriter.outdent();

		sourceWriter.println("}");

		return true;
	}
}
